package com.company.anr.service;

import com.company.anr.config.AnrConfig;
import com.company.anr.utils.FileUtils;
import com.company.anr.service.FileProcessingService;
import io.github.bonigarcia.wdm.WebDriverManager;
import org.openqa.selenium.*;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.remote.RemoteWebDriver;
import org.openqa.selenium.support.ui.WebDriverWait;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.logging.LogEntry;
import org.openqa.selenium.logging.LogEntries;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.time.Duration;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.io.File;

@Service
public class WebAutomationService {

  private static final Logger logger = LoggerFactory.getLogger(WebAutomationService.class);

  @Autowired
  private FileProcessingService fileProcessingService;

  @Autowired
  private AnrConfig anrConfig;

  // 配置信息
  private static final String LOGIN_URL = "https://iot-admin.zuoyebang.cc/iot-admin-server/index";
  private static final String ERROR_LOG_URL = "https://iot-admin.zuoyebang.cc/iot-admin-server/system/errorlog/table";
  private static final int DEFAULT_TIMEOUT = 10;
  private static final int DOWNLOAD_TIMEOUT = 300; // 5分钟

  private WebDriver driver;
  private WebDriverWait wait;

  /**
   * 初始化浏览器 - 强制使用远程调试方案（连接手动启动的Chrome）
   */
  public void initializeBrowser() {
    logger.info("开始初始化浏览器 - 强制使用远程调试方案...");
    try {
      initializeBrowserWithRemoteDebug();
    } catch (Exception e) {
      logger.error("远程调试方案失败: {}", e.getMessage());
      logger.error("错误详情: ", e);
      throw new RuntimeException("无法连接到Chrome调试实例，请确保Chrome以调试模式启动: " + e.getMessage(), e);
    }
  }

  /**
   * 方案1：远程调试端口方案（优先使用）
   */
  private void initializeBrowserWithRemoteDebug() throws MalformedURLException {
    logger.info("开始初始化浏览器 - 使用远程调试端口方案...");

    // 首先检查Chrome调试端口是否可用
    if (!isChromeDebugPortAvailable()) {
      throw new RuntimeException("Chrome调试端口9222不可用，请先运行start-chrome-debug.bat启动Chrome调试模式");
    }

    logger.info("Chrome调试端口9222可用，开始连接...");

    // 设置ChromeDriver路径
    System.setProperty("webdriver.chrome.driver", "C:\\Windows\\chromedriver.exe");

    ChromeOptions options = new ChromeOptions();

    // 关键：连接到手动启动的Chrome调试实例
    options.setExperimentalOption("debuggerAddress", "127.0.0.1:9222");
    logger.info("设置debuggerAddress: 127.0.0.1:9222");

    // 避免被检测为自动化
    options.addArguments("--disable-blink-features=AutomationControlled");
    options.addArguments("--disable-extensions");
    options.addArguments("--no-sandbox");
    options.addArguments("--disable-dev-shm-usage");

    logger.info("使用ChromeDriver连接到调试实例...");
    try {
      // 使用ChromeDriver连接到调试实例
      driver = new ChromeDriver(options);
      logger.info("成功连接到Chrome调试实例！");
    } catch (Exception e) {
      logger.error("连接Chrome调试实例失败: {}", e.getMessage());
      logger.error("错误详情: ", e);
      throw new RuntimeException("无法连接到Chrome调试实例: " + e.getMessage(), e);
    }

    logger.info("设置窗口大小...");
    driver.manage().window().maximize();

    logger.info("创建WebDriverWait...");
    wait = new WebDriverWait(driver, Duration.ofSeconds(DEFAULT_TIMEOUT));

    logger.info("浏览器初始化成功 - 已接管现有Chrome窗口");

    // 自动访问IoT平台
    logger.info("自动访问IoT平台...");
    driver.get(LOGIN_URL);
    try {
      Thread.sleep(3000); // 等待页面加载
    } catch (InterruptedException e) {
      logger.warn("等待页面加载时被中断: {}", e.getMessage());
      Thread.currentThread().interrupt();
    }
    logger.info("IoT平台页面已打开，等待用户登录");
  }

  /**
   * 检查Chrome调试端口是否可用
   */
  private boolean isChromeDebugPortAvailable() {
    try {
      java.net.Socket socket = new java.net.Socket("localhost", 9222);
      socket.close();
      logger.info("Chrome调试端口9222可用");
      return true;
    } catch (Exception e) {
      logger.warn("Chrome调试端口9222不可用: {}", e.getMessage());
      return false;
    }
  }

  /**
   * 初始化浏览器 - 方案1：复用用户配置文件方案（备选）
   */
  private void initializeBrowserWithLocalProfile() {
    try {
      logger.info("开始初始化浏览器 - 使用本地配置文件方案...");

      // 设置ChromeDriver路径
      System.setProperty("webdriver.chrome.driver", "C:\\Windows\\chromedriver.exe");

      ChromeOptions options = new ChromeOptions();

      // 使用本地Chrome配置文件（请替换<你的用户名>为实际用户名）
      options.addArguments("user-data-dir=C:\\Users\\FX\\AppData\\Local\\Google\\Chrome\\User Data");
      options.addArguments("profile-directory=Default");

      // 避免被检测为自动化
      options.addArguments("--disable-blink-features=AutomationControlled");
      options.setExperimentalOption("excludeSwitches", new String[] { "enable-automation" });
      options.setExperimentalOption("useAutomationExtension", false);

      // 下载配置
      Map<String, Object> prefs = new HashMap<>();
      prefs.put("download.default_directory", anrConfig.getWorkDirectory());
      prefs.put("download.prompt_for_download", false);
      prefs.put("download.directory_upgrade", true);
      prefs.put("safebrowsing.enabled", false); // 若失败，试改回true
      options.setExperimentalOption("prefs", prefs);

      // 可选日志捕获
      options.setCapability("goog:loggingPrefs", Map.of("browser", "ALL"));

      logger.info("创建ChromeDriver实例...");
      driver = new ChromeDriver(options);

      logger.info("设置窗口大小...");
      driver.manage().window().maximize();

      logger.info("创建WebDriverWait...");
      wait = new WebDriverWait(driver, Duration.ofSeconds(DEFAULT_TIMEOUT));

      logger.info("浏览器初始化成功 - 使用本地配置文件");
    } catch (Exception e) {
      logger.error("本地配置文件方案也失败: {}", e.getMessage(), e);
      throw new RuntimeException("所有浏览器初始化方案都失败: " + e.getMessage(), e);
    }
  }

  /**
   * 测试方法：模拟下载日志（用于测试其他功能）
   */
  public String testDownloadDeviceLogs(String deviceSn, String phone) {
    logger.info("测试模式：模拟下载设备日志 - SN: {}, Phone: {}", deviceSn, phone);

    // 创建一个模拟的下载文件名
    String mockFilename = "test_log_" + deviceSn + "_" + System.currentTimeMillis() + ".zip";

    // 创建下载目录
    try {
      java.nio.file.Files.createDirectories(java.nio.file.Paths.get(anrConfig.getWorkDirectory()));

      // 创建一个空的测试文件
      java.nio.file.Path testFile = java.nio.file.Paths.get(anrConfig.getWorkDirectory(), mockFilename);
      java.nio.file.Files.write(testFile, "Test log file content".getBytes());

      logger.info("测试文件创建成功: {}", testFile);
      return mockFilename;
    } catch (Exception e) {
      logger.error("创建测试文件失败: {}", e.getMessage());
      throw new RuntimeException("创建测试文件失败", e);
    }
  }

  /**
   * 登录网站
   *
   * @param username 用户名
   * @param password 密码
   */
  public void login(String username, String password) {
    try {
      logger.info("开始登录，访问URL: {}", LOGIN_URL);
      driver.get(LOGIN_URL);

      // 等待页面完全加载 - 增加等待时间
      try {
        Thread.sleep(5000);
      } catch (InterruptedException e) {
        logger.warn("等待页面加载时被中断: {}", e.getMessage());
        Thread.currentThread().interrupt();
      }

      logger.info("等待页面元素加载...");
      // 等待页面加载 - 使用更长的超时时间
      WebDriverWait longWait = new WebDriverWait(driver, Duration.ofSeconds(30));
      longWait.until(ExpectedConditions.presenceOfElementLocated(
          By.className("el-input__inner")));

      logger.info("找到输入框，开始输入用户名和密码");
      // 输入用户名和密码，前端那边就默认写成自己的
      driver.findElement(By.xpath("//input[@placeholder='请输入邮箱前缀']"))
          .sendKeys(username);
      driver.findElement(By.xpath("//input[@placeholder='请输入密码']"))
          .sendKeys(password);

      // 点击登录按钮
      logger.info("点击登录按钮");
      driver.findElement(By.cssSelector("button[type='button']")).click();

      try {
        Thread.sleep(3000); // 等待登录完成
      } catch (InterruptedException e) {
        logger.warn("等待登录完成时被中断: {}", e.getMessage());
        Thread.currentThread().interrupt();
      }
      logger.info("登录成功");

    } catch (Exception e) {
      logger.error("登录失败: {}", e.getMessage());
      // 保存页面截图用于调试
      try {
        String screenshotPath = "D:/ANR-WORK/login_error_" + System.currentTimeMillis() + ".png";
        ((TakesScreenshot) driver).getScreenshotAs(OutputType.FILE).renameTo(new java.io.File(screenshotPath));
        logger.info("登录失败截图已保存: {}", screenshotPath);
      } catch (Exception screenshotException) {
        logger.error("保存截图失败: {}", screenshotException.getMessage());
      }
      throw new RuntimeException("登录失败", e);
    }
  }

  /**
   * 下载设备日志 - 完全按照Python脚本的逻辑实现
   *
   * @param deviceSn 设备SN
   * @param phone    手机号
   * @return 下载的文件名
   */
  public String downloadDeviceLogs(String deviceSn, String phone) {
    try {
      logger.info("开始执行设备日志下载流程 - SN: {}, Phone: {}", deviceSn, phone);

      // 步骤1: 直接跳转到日志页面（完全按照Python脚本）
      logger.info("步骤1: 直接跳转到日志管理页面");
      driver.get(ERROR_LOG_URL);

      // 等待页面加载
      try {
        Thread.sleep(3000);
      } catch (InterruptedException e) {
        Thread.currentThread().interrupt();
      }

      // 步骤2: 定位输入框（完全按照Python脚本的XPath）
      logger.info("步骤2: 定位输入框");
      WebElement firstSnInput = driver.findElement(
          By.xpath("//*[@id=\"form-key-get\"]/div/div/div/div[1]/input"));
      WebElement secondSnInput = driver.findElement(
          By.xpath("//*[@id=\"form-search\"]/div/ul/li[1]/input"));
      WebElement phoneInput = driver.findElement(
          By.xpath("//*[@id=\"form-key-get\"]/div/div/div/div[3]/input"));

//      // 步骤3: 填写手机号和SN（完全按照Python脚本）
//      logger.info("步骤3: 填写手机号和SN");
//      phoneInput.sendKeys(phone);
//      firstSnInput.sendKeys(deviceSn);
//
//      // 步骤4: 点击通知按钮并处理设备状态（完全按照Python脚本）
//      logger.info("步骤4: 点击通知按钮并检查设备状态");
//      if (!checkDeviceStatusAndNotify()) {
//        throw new RuntimeException("设备不在线或状态检查失败");
//      }

      // 步骤5: 等待配置的时间（从配置文件读取）
      int waitSeconds = anrConfig.getAutomationNotificationWaitSeconds();
      logger.info("步骤5: 等待{}秒（从配置文件读取）", waitSeconds);
      try {
        Thread.sleep(waitSeconds * 1000);
      } catch (InterruptedException e) {
        Thread.currentThread().interrupt();
        throw new RuntimeException("等待过程被中断");
      }

      // 步骤6: 填写第二个SN输入框并搜索（完全按照Python脚本）
      logger.info("步骤6: 填写第二个SN输入框并搜索");
      secondSnInput.sendKeys(deviceSn);

      // 点击搜索按钮（完全按照Python脚本的XPath）
      wait.until(ExpectedConditions.elementToBeClickable(
          By.xpath("//*[@id=\"form-search\"]/div/ul/li[2]/a[1]"))).click();

      // 步骤7: 下载文件（完全按照Python脚本）
      logger.info("步骤7: 下载文件");
      return waitAndDownloadPythonStyle();

    } catch (Exception e) {
      logger.error("下载设备日志失败: {}", e.getMessage());
      throw new RuntimeException("下载设备日志失败", e);
    }
  }

  /**
   * 步骤3: 填写设备信息并发送通知
   *
   * @param deviceSn 设备SN
   * @param phone    手机号
   * @return 是否成功
   */
  private boolean fillDeviceInfoAndNotify(String deviceSn, String phone) {
    try {
      logger.info("开始填写设备信息 - SN: {}, Phone: {}", deviceSn, phone);

      // 定位输入框 - 使用Python脚本相同的XPath
      WebElement firstSnInput = driver.findElement(
          By.xpath("//*[@id=\"form-key-get\"]/div/div/div/div[1]/input"));
      WebElement phoneInput = driver.findElement(
          By.xpath("//*[@id=\"form-key-get\"]/div/div/div/div[3]/input"));

      // 清空输入框并填写信息
      firstSnInput.clear();
      firstSnInput.sendKeys(deviceSn);

      phoneInput.clear();
      phoneInput.sendKeys(phone);

      logger.info("设备信息填写完成，开始检查设备状态");

      // 检查设备状态并发送通知
      return checkDeviceStatusAndNotify();

    } catch (Exception e) {
      logger.error("填写设备信息失败: {}", e.getMessage());
      return false;
    }
  }

  /**
   * 检查设备状态并发送通知
   *
   * @return 设备是否在线
   */
  private boolean checkDeviceStatusAndNotify() {
    try {
      int clickCount = 1;
      while (true) {
        // 点击发送日志上传通知按钮 - 使用Python脚本相同的XPath
        wait.until(ExpectedConditions.elementToBeClickable(
            By.xpath("/html/body/div[2]/div/button"))).click();

        // 处理通知提示框 - 使用Python脚本相同的逻辑
        WebElement messageElement = wait.until(ExpectedConditions.presenceOfElementLocated(
            By.xpath("//*[@id=\"layui-layer" + clickCount + "\"]/div[2]")));
        String message = messageElement.getText();
        logger.info("设备状态消息: {}", message);

        // 确认消息
        wait.until(ExpectedConditions.elementToBeClickable(
            By.xpath("//*[@id=\"layui-layer" + clickCount + "\"]/div[3]/a"))).click();

        clickCount++;

        if (message.contains("设备不在线")) {
          logger.warn("设备不在线，请确认设备在线后重试");
          // 根据Python脚本逻辑，设备不在线时应该等待用户确认
          // 这里可以选择抛出异常或者返回false，让调用者决定如何处理
          return false;
        } else {
          logger.info("设备状态检查通过，通知发送成功");
          return true;
        }
      }
    } catch (Exception e) {
      logger.error("检查设备状态失败: {}", e.getMessage());
      return false;
    }
  }

  /**
   * 步骤5: 搜索并下载日志文件
   *
   * @param deviceSn 设备SN
   * @return 下载的文件名
   */
  private String searchAndDownloadLogs(String deviceSn) {
    try {
      logger.info("开始搜索设备日志 - SN: {}", deviceSn);

      // 定位第二个SN输入框并填写
      WebElement secondSnInput = driver.findElement(
          By.xpath("//*[@id=\"form-search\"]/div/ul/li[1]/input"));
      secondSnInput.clear();
      secondSnInput.sendKeys(deviceSn);

      // 点击搜索按钮 - 使用Python脚本相同的XPath
      wait.until(ExpectedConditions.elementToBeClickable(
          By.xpath("//*[@id=\"form-search\"]/div/ul/li[2]/a[1]"))).click();

      logger.info("搜索完成，开始等待下载链接出现");

      // 等待下载链接出现并下载
      return waitAndDownloadPythonStyle();

    } catch (Exception e) {
      logger.error("搜索日志失败: {}", e.getMessage());
      throw new RuntimeException("搜索日志失败", e);
    }
  }

  /**
   * 等待下载链接出现并下载
   *
   * @return 下载的文件名
   */
  private String waitAndDownload() {
    try {
      logger.info("开始等待下载链接出现...");

      // 等待页面完全加载
      try {
        Thread.sleep(3000);
      } catch (InterruptedException e) {
        logger.warn("等待页面加载时被中断: {}", e.getMessage());
        Thread.currentThread().interrupt();
      }

      // 使用Python脚本相同的选择器策略
      List<WebElement> downloadLinks = null;

      // 策略1: 使用Python脚本相同的XPath选择器
      try {
        downloadLinks = wait.until(driver -> {
          List<WebElement> elements = driver.findElements(By.xpath("//*[@id=\"bootstrap-table\"]/tbody/tr/td[6]/a"));
          return elements.isEmpty() ? null : elements;
        });
        logger.info("使用Python脚本相同的XPath选择器找到 {} 个下载链接", downloadLinks.size());
      } catch (Exception e) {
        logger.warn("Python脚本XPath选择器查找失败，尝试备用选择器: {}", e.getMessage());
      }

      // 策略2: 备用选择器 - 查找表格中的下载按钮
      if (downloadLinks == null || downloadLinks.isEmpty()) {
        try {
          downloadLinks = wait.until(driver -> {
            List<WebElement> elements = driver.findElements(By.cssSelector("table a.btn.btn-success.btn-xs"));
            return elements.isEmpty() ? null : elements;
          });
          logger.info("使用备用CSS选择器找到 {} 个下载链接", downloadLinks.size());
        } catch (Exception e) {
          logger.warn("备用CSS选择器查找失败，尝试通用选择器: {}", e.getMessage());
        }
      }

      // 策略3: 通用选择器
      if (downloadLinks == null || downloadLinks.isEmpty()) {
        try {
          downloadLinks = wait.until(driver -> {
            List<WebElement> allLinks = driver.findElements(By.tagName("a"));
            List<WebElement> downloadElements = allLinks.stream()
                .filter(element -> element.getText().contains("下载"))
                .collect(java.util.stream.Collectors.toList());
            return downloadElements.isEmpty() ? null : downloadElements;
          });
          logger.info("使用通用选择器找到 {} 个下载链接", downloadLinks.size());
        } catch (Exception e) {
          logger.error("所有选择器都失败了: {}", e.getMessage());
        }
      }

      if (downloadLinks == null || downloadLinks.isEmpty()) {
        // 保存页面截图用于调试
        try {
          String screenshotPath = "D:/ANR-WORK/download_error_" + System.currentTimeMillis() + ".png";
          ((TakesScreenshot) driver).getScreenshotAs(OutputType.FILE).renameTo(new File(screenshotPath));
          logger.error("未找到下载链接，截图已保存: {}", screenshotPath);
        } catch (Exception screenshotException) {
          logger.error("保存截图失败: {}", screenshotException.getMessage());
        }
        throw new RuntimeException("未找到下载链接");
      }

      // 选择第一个下载链接（最新的）- 根据用户要求
      int index = 0; // 选择第一个
      WebElement downloadLink = downloadLinks.get(index);
      logger.info("找到 {} 个下载链接，选择第{}个（第一个/最新的）", downloadLinks.size(), index + 1);

      // 获取期望的文件名
      String href = downloadLink.getAttribute("href");
      logger.info("下载链接href: {}", href);

      String expectedFilename = FileUtils.extractFilenameFromUrl(href);
      logger.info("期望的文件名: {}", expectedFilename);

      // 滚动到元素可见
      ((JavascriptExecutor) driver).executeScript("arguments[0].scrollIntoView(true);", downloadLink);
      try {
        Thread.sleep(1000);
      } catch (InterruptedException e) {
        logger.warn("等待滚动完成时被中断: {}", e.getMessage());
        Thread.currentThread().interrupt();
      }

      // 点击下载
      try {
        downloadLink.click();
        logger.info("成功点击下载按钮");
      } catch (Exception clickException) {
        logger.warn("普通点击失败，尝试JavaScript点击: {}", clickException.getMessage());
        ((JavascriptExecutor) driver).executeScript("arguments[0].click();", downloadLink);
        logger.info("使用JavaScript成功点击下载按钮");
      }

      // 等待一下让下载开始
      try {
        Thread.sleep(5000);
      } catch (InterruptedException e) {
        logger.warn("等待下载开始时被中断: {}", e.getMessage());
        Thread.currentThread().interrupt();
      }

      // 等待文件下载完成
      Path downloadDir = Paths.get(anrConfig.getWorkDirectory());

      // 先列出下载目录中的所有文件，用于调试
      try {
        logger.info("下载前目录内容:");
        Files.list(downloadDir).forEach(path -> logger.info("  - {}", path.getFileName()));
      } catch (IOException e) {
        logger.warn("无法列出下载目录内容: {}", e.getMessage());
      }

      // 增加等待时间到10分钟
      Path downloadedFile = FileUtils.waitForFile(downloadDir, expectedFilename, 600);

      if (downloadedFile != null) {
        logger.info("文件下载完成: {}", downloadedFile);
        return downloadedFile.getFileName().toString();
      } else {
        // 下载失败时，再次列出目录内容
        try {
          logger.error("下载失败，当前下载目录内容:");
          Files.list(downloadDir).forEach(path -> logger.error("  - {}", path.getFileName()));
        } catch (IOException e) {
          logger.error("无法列出下载目录内容: {}", e.getMessage());
        }
        throw new RuntimeException("文件下载超时");
      }

    } catch (Exception e) {
      logger.error("等待下载失败: {}", e.getMessage());
      throw new RuntimeException("等待下载失败", e);
    }
  }

  /**
   * 关闭浏览器
   */
  public void closeBrowser() {
    if (driver != null) {
      try {
        // 输出浏览器日志用于调试下载问题
        try {
          LogEntries logEntries = driver.manage().logs().get("browser");
          logger.info("浏览器日志条目数: {}", logEntries.getAll().size());
          for (LogEntry entry : logEntries.getAll()) {
            // 输出所有日志用于调试
            System.out.println("浏览器日志: " + entry.getMessage());
            // 特别关注下载相关日志
            if (entry.getMessage().contains("download") || entry.getMessage().contains("error")
                || entry.getMessage().contains("blocked")) {
              logger.warn("重要浏览器日志: {}", entry.getMessage());
            }
          }
        } catch (Exception logException) {
          logger.warn("获取浏览器日志失败: {}", logException.getMessage());
        }

        driver.quit();
        logger.info("浏览器已关闭");
      } catch (Exception e) {
        logger.error("关闭浏览器时出错: {}", e.getMessage());
      }
    }
  }

  /**
   * 检查浏览器是否已初始化
   *
   * @return 是否已初始化
   */
  public boolean isInitialized() {
    return driver != null;
  }

  /**
   * 使用Python脚本相同的下载逻辑
   * 这个方法完全复制Python脚本的下载机制
   */
  public String downloadDeviceLogsPythonStyle(String deviceSn, String phone) {
    try {
      // 打开错误日志页面
      driver.get(ERROR_LOG_URL);

      // 定位输入框 - 使用Python脚本相同的选择器
      WebElement firstSnInput = driver.findElement(
          By.xpath("//*[@id=\"form-key-get\"]/div/div/div/div[1]/input"));
      WebElement secondSnInput = driver.findElement(
          By.xpath("//*[@id=\"form-search\"]/div/ul/li[1]/input"));
      WebElement phoneInput = driver.findElement(
          By.xpath("//*[@id=\"form-key-get\"]/div/div/div/div[3]/input"));

      // 填写信息
      firstSnInput.sendKeys(deviceSn);
      phoneInput.sendKeys(phone);

      // 检查设备状态
      if (!checkDeviceStatusAndNotify()) {
        throw new RuntimeException("设备不在线或状态检查失败");
      }

      // 填写第二个SN输入框
      secondSnInput.sendKeys(deviceSn);

      // 点击搜索按钮 - 使用Python脚本相同的选择器
      wait.until(ExpectedConditions.elementToBeClickable(
          By.xpath("//*[@id=\"form-search\"]/div/ul/li[2]/a[1]"))).click();

      // 等待下载链接出现并下载 - 使用Python脚本相同的逻辑
      return waitAndDownloadPythonStyle();

    } catch (Exception e) {
      logger.error("下载设备日志失败: {}", e.getMessage());
      throw new RuntimeException("下载设备日志失败", e);
    }
  }

  /**
   *
   */
  private String waitAndDownloadPythonStyle() {
    try {
      logger.info("开始等待下载链接出现...");

      // 等待页面完全加载
      try {
        Thread.sleep(3000);
      } catch (InterruptedException e) {
        logger.warn("等待页面加载时被中断: {}", e.getMessage());
        Thread.currentThread().interrupt();
      }

      // 使用Python脚本完全相同的选择器和逻辑
      List<WebElement> downloadLinks = wait.until(driver -> {
        List<WebElement> elements = driver.findElements(By.xpath("//*[@id=\"bootstrap-table\"]/tbody/tr/td[6]/a"));
        return elements.isEmpty() ? null : elements;
      });

      if (downloadLinks == null || downloadLinks.isEmpty()) {
        throw new RuntimeException("未找到下载链接");
      }

      // 选择第一个（最新的）下载链接
      int index = 0; // 选择第一个（最新的）
      WebElement downloadLink = downloadLinks.get(index);
      logger.info("找到 {} 个下载链接，选择第{}个（第一个/最新的）", downloadLinks.size(), index + 1);

      // 获取期望的文件名（完全按照Python脚本）
      String href = downloadLink.getAttribute("href");
      logger.info("下载链接href: {}", href);

      String expectedFilename = FileUtils.extractFilenameFromUrl(href);
      logger.info("期望的文件名: {}", expectedFilename);

      // 直接点击下载（完全按照Python脚本）
      downloadLink.click();
      logger.info("成功点击下载按钮");

      // 等待文件下载完成
      Path downloadDir = Paths.get(anrConfig.getWorkDirectory());

      // 等待文件下载完成（完全按照Python脚本的等待逻辑）
      Path downloadedFile = FileUtils.waitForFile(downloadDir, expectedFilename, 1600);

      if (downloadedFile != null) {
        logger.info("文件下载完成: {}", downloadedFile);
        return downloadedFile.getFileName().toString();
      } else {
        throw new RuntimeException("文件下载超时");
      }

    } catch (Exception e) {
      logger.error("等待下载失败: {}", e.getMessage());
      throw new RuntimeException("等待下载失败", e);
    }
  }

  /**
   * 调试方法：分析页面中的下载按钮
   * 这个方法可以帮助您了解页面结构，用于调试下载问题
   */
  public void debugDownloadButtons() {
    try {
      logger.info("开始调试页面中的下载按钮...");

      // 等待页面加载
      try {
        Thread.sleep(3000);
      } catch (InterruptedException e) {
        logger.warn("等待页面加载时被中断: {}", e.getMessage());
        Thread.currentThread().interrupt();
      }

      // 1. 查找所有包含"下载"文本的元素
      List<WebElement> allDownloadElements = driver.findElements(By.xpath("//*[contains(text(), '下载')]"));
      logger.info("找到 {} 个包含'下载'文本的元素", allDownloadElements.size());

      for (int i = 0; i < allDownloadElements.size(); i++) {
        WebElement element = allDownloadElements.get(i);
        logger.info("元素 {}: 标签={}, 文本={}, 类名={}",
            i + 1,
            element.getTagName(),
            element.getText().trim(),
            element.getAttribute("class"));
      }

      // 2. 查找所有按钮样式的链接
      List<WebElement> buttonLinks = driver.findElements(By.cssSelector("a.btn"));
      logger.info("找到 {} 个按钮样式的链接", buttonLinks.size());

      for (int i = 0; i < buttonLinks.size(); i++) {
        WebElement element = buttonLinks.get(i);
        logger.info("按钮链接 {}: 文本={}, 类名={}, href={}",
            i + 1,
            element.getText().trim(),
            element.getAttribute("class"),
            element.getAttribute("href"));
      }

      // 3. 查找表格中的下载链接
      List<WebElement> tableLinks = driver.findElements(By.cssSelector("table a"));
      logger.info("找到 {} 个表格中的链接", tableLinks.size());

      for (int i = 0; i < tableLinks.size(); i++) {
        WebElement element = tableLinks.get(i);
        if (element.getText().contains("下载")) {
          logger.info("表格下载链接 {}: 文本={}, 类名={}, href={}",
              i + 1,
              element.getText().trim(),
              element.getAttribute("class"),
              element.getAttribute("href"));
        }
      }

      // 4. 保存页面截图
      String screenshotPath = "D:/ANR-WORK/debug_page_" + System.currentTimeMillis() + ".png";
      ((TakesScreenshot) driver).getScreenshotAs(OutputType.FILE).renameTo(new File(screenshotPath));
      logger.info("调试截图已保存: {}", screenshotPath);

      // 5. 获取页面HTML源码（部分）
      String pageSource = driver.getPageSource();
      if (pageSource.length() > 10000) {
        pageSource = pageSource.substring(0, 10000) + "...";
      }
      logger.info("页面源码片段: {}", pageSource);

    } catch (Exception e) {
      logger.error("调试下载按钮时出错: {}", e.getMessage(), e);
    }
  }

  /**
   * 完整的自动化流程 - 模拟Python脚本的完整功能
   * 这个方法实现了图片中显示的5个步骤，并在下载完成后自动处理文件
   *
   * @param username 用户名
   * @param password 密码
   * @param deviceSn 设备SN
   * @param phone    手机号
   * @return 下载的文件名
   */
  public String executeFullAutomationWorkflow(String username, String password, String deviceSn, String phone) {
    try {
      logger.info("开始执行完整的自动化工作流程");
      logger.info("参数 - 用户名: {}, 设备SN: {}, 手机号: {}", username, deviceSn, phone);

      // 确保浏览器已初始化
      if (!isInitialized()) {
        logger.info("浏览器未初始化，开始初始化...");
        initializeBrowser();
      }

      // 跳过登录步骤，因为用户已经手动登录了
      logger.info("跳过登录步骤，用户已手动登录");

      // 直接执行5步流程
      logger.info("开始执行5步自动化流程");
      String downloadedFile = downloadDeviceLogs(deviceSn, phone);

      logger.info("自动化工作流程执行完成，下载文件: {}", downloadedFile);

      // 下载完成后，自动触发文件处理流程
      if (downloadedFile != null && !downloadedFile.isEmpty()) {
        logger.info("开始自动处理下载的文件: {}", downloadedFile);
        processDownloadedFile(downloadedFile, deviceSn);
      }

      return downloadedFile;

    } catch (Exception e) {
      logger.error("自动化工作流程执行失败: {}", e.getMessage());
      throw new RuntimeException("自动化工作流程执行失败", e);
    }
  }

  /**
   * 简化的自动化流程 - 适用于已经登录的情况
   *
   * @param deviceSn 设备SN
   * @param phone    手机号
   * @return 下载的文件名
   */
  public String executeDeviceLogDownload(String deviceSn, String phone) {
    try {
      logger.info("开始执行设备日志下载流程 - SN: {}, Phone: {}", deviceSn, phone);

      // 确保浏览器已初始化
      if (!isInitialized()) {
        throw new RuntimeException("浏览器未初始化，请先调用initializeBrowser()");
      }

      // 执行完整的5步流程
      String downloadedFile = downloadDeviceLogs(deviceSn, phone);

      logger.info("设备日志下载流程执行完成，下载文件: {}", downloadedFile);

      // 下载完成后，自动触发文件处理流程
      if (downloadedFile != null && !downloadedFile.isEmpty()) {
        logger.info("开始自动处理下载的文件: {}", downloadedFile);
        processDownloadedFile(downloadedFile, deviceSn);
      }

      return downloadedFile;

    } catch (Exception e) {
      logger.error("设备日志下载流程执行失败: {}", e.getMessage());
      throw new RuntimeException("设备日志下载流程执行失败", e);
    }
  }

  /**
   * 处理下载的文件 - 解压、重命名、解析ANR日志
   *
   * @param downloadedFile 下载的文件名
   * @param deviceSn       设备SN
   */
  private void processDownloadedFile(String downloadedFile, String deviceSn) {
    try {
      logger.info("开始处理下载的文件: {} for SN: {}", downloadedFile, deviceSn);

      // 等待文件完全下载
      Path downloadDir = Paths.get(anrConfig.getWorkDirectory());
      Path zipFile = downloadDir.resolve(downloadedFile);

      // 等待文件存在
      int maxWaitTime = 30; // 最多等待30秒
      int waitTime = 0;
      while (!Files.exists(zipFile) && waitTime < maxWaitTime) {
        try {
          Thread.sleep(1000);
          waitTime++;
        } catch (InterruptedException e) {
          Thread.currentThread().interrupt();
          throw new RuntimeException("等待文件下载时被中断", e);
        }
      }

      if (!Files.exists(zipFile)) {
        logger.error("下载的文件不存在: {}", zipFile);
        return;
      }

      logger.info("文件下载完成，开始解压和处理: {}", zipFile);

      // 创建输出目录
      Path outputDir = Paths.get(anrConfig.getWorkPathForSn(deviceSn));
      Path detailDir = Paths.get(anrConfig.getDetailDirectory());

      // 创建DETAIL目录（如果不存在）
      Files.createDirectories(detailDir);

      // 使用FileProcessingService处理文件
      boolean success = fileProcessingService.extractAndCopy(zipFile, downloadDir, outputDir);

      if (success) {
        // 生成分析报告到DETAIL目录
        Path anrFolder = outputDir.resolve("anr");
        Path detailReportFile = Paths.get(anrConfig.getDetailReportPathForSn(deviceSn));

        if (Files.exists(anrFolder)) {
          fileProcessingService.processAnrFolder(anrFolder, detailReportFile);
          logger.info("分析报告已生成: {}", detailReportFile);
        } else {
          // 即使没有anr文件夹，也要生成analysis.txt文件
          logger.info("anr文件夹不存在，生成无ANR日志报告");
          fileProcessingService.generateNoAnrReport(detailReportFile);
          logger.info("无ANR日志报告已生成: {}", detailReportFile);
        }

        // 创建以SN命名的文件夹并复制文件
        // 使用getProcessedPathForSn获取按日期分类的路径
        Path snFolder = Paths.get(anrConfig.getProcessedPathForSn(deviceSn));
        Files.createDirectories(snFolder.getParent()); // 确保MM-dd目录存在
        fileProcessingService.createSnFolderAndCopyFiles(outputDir, snFolder);
        logger.info("已创建SN文件夹: {}", snFolder);

        logger.info("文件处理完成，输出目录: {}", outputDir);
        logger.info("SN文件夹: {}", snFolder);
        logger.info("详细分析报告: {}", detailReportFile);
      } else {
        logger.error("文件处理失败");
      }

    } catch (Exception e) {
      logger.error("处理下载文件时出错: {}", e.getMessage(), e);
    }
  }

}